---
title: Accessibility
redirect_from:
  - /components/popover/accessibility/
---

## Accessibility

The Popover component has been designed with accessibility in mind, providing features that enhance the experience for users of assistive technologies.

### Accessibility props

The following props are available to improve the accessibility of your Popover component:

| Prop           | Type                                                  | Default    | Description                                                                                                                      |
| :------------- | :---------------------------------------------------- | :--------- | :------------------------------------------------------------------------------------------------------------------------------- |
| ariaLabel      | `string`                                              |            | Adds `aria-label` to the popover content, providing a description for screen readers.                                            |
| ariaLabelledby | `string`                                              |            | References the ID of an element that labels the popover content for screen readers.                                              |
| role           | `"dialog" \| "menu" \| "grid" \| "listbox" \| "tree"` | `"dialog"` | Defines the ARIA role of the popover component.                                                                                  |
| labelClose     | `React.Node`                                          | `"Close"`  | The label for the close button displayed on mobile devices.                                                                      |
| tabIndex       | `number`                                              |            | Controls the tab order of the trigger element. Useful when placing popover in controlled focus contexts like grids.              |
| triggerRole    | `string`                                              |            | Sets the ARIA role of the trigger element. Useful for specialized contexts like `"gridcell"` when using popover in tables/grids. |

### Automatic Accessibility Features

The Popover component automatically handles several important ARIA attributes on the trigger element:

- `aria-controls`: Links the trigger element to the popover content using a unique ID or `id` provided via props.
- `aria-haspopup`: Indicates that the trigger reveals additional content (set to the popover's role).
- `aria-expanded`: Indicates whether the popover is currently visible or hidden.

These attributes are managed by the component and do not need to be manually added to your code.

The trigger element is rendered with `role="button"` by default, but this can be customized using the `triggerRole` prop for specialized contexts.

The trigger element has `tabIndex="0"` by default, making it focusable and following the natural tab order. You can set `tabIndex="-1"` to make it non-focusable when needed, but ensure focus is still properly handled for keyboard accessibility.

### Best practices

#### Non-interactive trigger elements

The Popover's trigger element (provided as `children`) should not be an interactive element like a native `<button>` or `<a>` tag, as this creates nested interactive elements which is an accessibility violation.

For example, if using a Button component as a trigger, set `asComponent="div"` to avoid this issue:

```jsx
<Popover content="Popover content">
  <Button asComponent="div">Open popover</Button>
</Popover>
```

#### Descriptive labels

- Provide meaningful `ariaLabel` or `ariaLabelledby` props to help screen reader users understand the purpose of the popover.
- The `ariaLabel` should be concise but descriptive, such as "Passenger selection" or "Filter options".
- When using `ariaLabelledby`, ensure the referenced element (by ID) contains clear, descriptive text that explains the popover's purpose.
- Always ensure that `ariaLabel` text and any text in elements referenced by `ariaLabelledby` are properly translated to match the user's language.

For example:

```jsx
// Using ariaLabel
<Popover ariaLabel="Passenger selection options" content={passengerSelectionContent}>
  <Button asComponent="div">Select passengers</Button>
</Popover>
```

```jsx
// Using ariaLabelledby
<div>
  <h2 id="passenger-selection-heading">Passenger selection</h2>
  <Popover ariaLabelledby="passenger-selection-heading" content={passengerSelectionContent}>
    <Button asComponent="div">Select passengers</Button>
  </Popover>
</div>
```

The `ariaLabel` and `ariaLabelledby` props provide important context about the popover's content to screen reader users. Always use one of these props to ensure your Popover is accessible.

#### Custom close label

When the popover is closable on mobile devices, the default "Close" label can be overridden with a more descriptive one using the `labelClose` prop.

```jsx
<Popover content="Popover content" labelClose="Close passenger selection">
  <Button asComponent="div">Select passengers</Button>
</Popover>
```

#### Keyboard navigation

The Popover component supports keyboard navigation:

- The popover can be opened by pressing <kbd>Enter</kbd> or <kbd>Space</kbd> when the trigger element has focus.
- When open, the popover can be closed by pressing <kbd>Escape</kbd>.
- Focus is properly managed within the popover when it's open.

#### Appropriate roles

The `role` prop should be chosen based on the popover's content and purpose:

- Use `"dialog"` (the default) for most cases, especially when presenting forms or information.
- Use `"menu"` when the popover contains a list of actions or menu items.
- Use `"listbox"` when presenting a list of selectable options.
- Use `"grid"` for tabular data.
- Use `"tree"` for hierarchical, expandable/collapsible content.

### Examples

#### Basic popover with proper labeling

```jsx
<Popover
  content={<Text>This is additional information about this feature.</Text>}
  ariaLabel="Feature information"
>
  <Button asComponent="div">More info</Button>
</Popover>
```

Screen readers would announce: "More info, dialogue pop-up collapsed, button" and when opened: "Feature information, dialog".

#### Popover with custom role and existing label

```jsx
<Stack>
  <h2 id="passenger-selection">Passenger selection</h2>
  <Popover
    content={
      <Stack>
        <Stepper
          minValue={0}
          ariaLabelValue="Number of adult passengers"
          titleIncrement="Add adult passenger"
          titleDecrement="Remove adult passenger"
        />
      </Stack>
    }
    role="menu"
    ariaLabelledby="passenger-selection"
  >
    <Button asComponent="div" iconRight={<ChevronDown />}>
      Select passengers
    </Button>
  </Popover>
</Stack>
```

In this example, screen readers would announce "Select passengers, menu pop-up collapsed, button" and when opened: "Passenger selection, menu".
